home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Medal Software 3
/
Gold Medal Software - Volume 3 (Gold Medal) (1994).iso
/
utils2
/
mymous12.arj
/
MM-HANDL.ASM
< prev
next >
Wrap
Assembly Source File
|
1994-01-06
|
10KB
|
375 lines
; MyMouse
; Input handler bit (to cut down the size of the source file)
; Andrew Forrest
;****************************************************************************
; Routine can't get semaphore since this causes deadlock when we try to
; change the parameters. For this reason, we must use only atomic variables.
;***************************************************************************
;***************************************************************************
; Takes a0=^oldEventChain; a1=^GlobalPtr; Returns d0=^newEventChain;
; Scratches d1, a0, a1
; Uses a4=^first link; a5=^global structure; d1=TimeStamp of last event
IntRoutine: ;Start of input handler code
pushm.l a4-a5
lea (a0),a4 ; First link in event chain
lea (a1),a5 ; Global Ptr
.loop push.l a0
bsr.s Do_Event
pop.l a0
move.l ie_NextEvent(a0),d0
beq.s .end_loop
move.l d0,a0
bra.s .loop
.end_loop move.l ie_TimeStamp+TV_SECS(a0),d1 ; time in seconds
bsr Time_Outs
move.l a4,d0
popm.l a4-a5
rts
;****************************************************************************
Do_Event:
; Takes a0=^Event; a5=^GlobalPtr;
; scratches d1, a0, a1
pushm.l a2/a6
move.l IntBase(a5),a6
;*╗╗ Perform SunMouse (Activate window)
tst.l SunMouseOption(a5)
beq.s .SkipSunMouse1
cmp.b #IECLASS_TIMER,ie_Class(a0)
bne.s .SkipSunMouse1
bclr #STB_SunMouse,Status(a5)
beq.s .SkipSunMouse1 ; Skip if already Sunned
bsr GetWindow
push.l a0
move.l d0,a0
cmp.l ib_ActiveWindow(a6),a0
beq.s .EndSun
just ActivateWindow
.EndSun: pop.l a0
.SkipSunMouse1:
cmp.b #IECLASS_TIMER,ie_Class(a0)
beq .not_key ; If it's a timer event, don't unblank
;*╗╗ Reset screen blank
move.l ie_TimeStamp(a0),ScreenTime(a5)
bclr #STB_SBlanked,Status(a5)
beq.s .SkipSRestore
UnBkScreen
.SkipSRestore
cmp.b #IECLASS_RAWKEY,ie_Class(a0)
bne .not_key ; skip this bit if not a key
;*╗╗ Do Northgate keyboard mapping.
tst.l NorthgateOption(a5)
beq.s .SkipNorthgate
lea NorthgateTable(pc),a2
move.w ie_Code(a0),d0
bclr #IECODEB_UP_PREFIX,d0
.NorthgateLoop:
move.b (a2),d1
beq.s .EndNorthgate
addq.l #3,a2
cmp.b d0,d1
bne.s .NorthgateLoop
and.w #IECODE_UP_PREFIX,ie_Code(a0)
move.b -2(a2),d0
or.b d0,ie_Code+1(a0)
move.b -1(a2),d0
or.b d0,ie_Qualifier+1(a0)
.EndNorthgate
.SkipNorthgate
move.w ie_Code(a0),d0
tst.b d0
bmi .end_event ;henceforth ignore key-ups
btst #IEQUALIFIERB_LCOMMAND,ie_Qualifier+1(a0)
bne.s .do_LAmiga
;*╗╗ Blank mouse pointer if not a qualifier key pressed
tst.l MouseBlank(a5)
bmi.s .NoMBlank
and.b #%11111000,d0 ; If raw key is 60 thru 67,
cmp.b #$60,d0 ; ...we shouldn't blank mouse
beq.s .NoMBlank ; ...('cos it was shift or something).
bset #STB_DoMBlank,Status(a5)
bsr SignalMouseBlank ; Blank mouse on keypress
.NoMBlank bra .end_event
.do_LAmiga:
;*╗╗ Check for Amiga-ESC
tst.l CmdOption(a5)
beq .end_event
cmp.w #KEYCODE_ESC,ie_Code(a0)
bne .end_event
clr.b ie_Class(a0)
move.l CLISig(a5),d0
bsr SignalTask
bra .end_event
.not_key:
move.w ib_MouseX(a6),d0
move.w ib_MouseY(a6),d1
cmp.b #IECLASS_RAWMOUSE,ie_Class(a0)
beq.s .do_mouse
cmp.w CurrentX(a5),d0
bne.s .do_mouse
cmp.w CurrentY(a5),d1
beq .end_event
.do_mouse: move.w d0,CurrentX(a5)
move.w d1,CurrentY(a5)
;*╗╗ Restore mouse pointer if the mouse moves
move.l ie_TimeStamp(a0),MouseTime(a5)
btst #STB_MBlanked,Status(a5)
bne.s .restore ; Restore mouse if we _know_ it's blanked
move.l ib_ActiveWindow(a6),d0 ; Examine active window
beq.s .no_restore ; Exit if no active window(!)
move.l d0,a1
move.l wd_Pointer(a1),d0
cmp.l MouseChipData(a5),d0
bne.s .no_restore ; Restore if it _turns out_ to be blanked
.restore bclr #STB_DoMBlank,Status(a5)
bsr SignalMouseBlank
.no_restore
;*╗╗ Test Sunnyness of mouse
tst.l SunMouseOption(a5)
beq.s .noSunMouse
move.w ie_Qualifier(a0),d0
and.w #IEQUALIFIER_LEFTBUTTON+IEQUALIFIER_RBUTTON+IEQUALIFIER_MIDBUTTON,d0
bne.s .noSunMouse
cmp.w #IECODE_LBUTTON+IECODE_UP_PREFIX,ie_Code(a0)
beq.s .noSunMouse
bset #STB_SunMouse,Status(a5)
.noSunMouse
;*╗╗ Perform click-to-back.
tst.l CTBOption(a5)
beq .no_CTB
cmp.w #IECODE_RBUTTON,ie_Code(a0)
bne .no_CTB
move.w ie_Qualifier(a0),d0
btst #IEQUALIFIERB_LEFTBUTTON,d0
beq .no_CTB
pushm.l d2/a0-a1
bsr GetWindow
tst.l d0
beq.s .end_CTB
move.l d0,a1
move.l wd_Flags(a1),d2
and.l #WFLG_BACKDROP,d2
bne.s .end_CTB
;Is this the only window on this screen, except for backdrop windows?
move.l wd_WScreen(a1),a1
move.l sc_FirstWindow(a1),a1
.back_loop cmp.l a1,d0
beq.s .endback_lp
move.l wd_Flags(a1),d2
and.l #WFLG_BACKDROP,d2
beq.s .flipwindow
.endback_lp move.l wd_NextWindow(a1),a1
move.l a1,d2
bne.s .back_loop
bra.s .end_CTB
.flipwindow move.l d0,a0
just WindowToBack
.end_CTB popm.l d2/a0-a1
clr.b ie_Class(a0)
bra .end_event
.no_CTB
;*╗╗ Perform click-to-front.
tst.l CTF(a5)
ble .no_CTF
cmp.w #IECODE_LBUTTON,ie_Code(a0)
bne .no_CTF
btst #IEQUALIFIERB_LCOMMAND,ie_Qualifier+1(a0)
bne .no_CTF ;to avoid interferring with Snap
bsr GetWindow
tst.l d0
beq .no_CTF
push.l d2
move.l CTFB(a5),d2
bmi.s .no_border
move.l d0,a1
btst #BBB_LEFT,d2
beq.s .test_right
.test_left move.w wd_MouseX(a1),d1
move.b wd_BorderLeft(a1),d0
ext.w d0
cmp.w d0,d1
blo.s .in_border
.test_right btst #BBB_RIGHT,d2
beq.s .test_top
move.b wd_BorderRight(a1),d0
ext.w d0
add.w d0,d1
cmp.w wd_Width(a1),d1
bhs.s .in_border
.test_top btst #BBB_TOP,d2
beq.s .test_botto
move.w wd_MouseY(a1),d1
move.b wd_BorderTop(a1),d0
ext.w d0
cmp.w d0,d1
blo.s .in_border
.test_botto btst #BBB_BOTTOM,d2
beq .end_CTF
move.b wd_BorderBottom(a1),d0
ext.w d0
add.w d0,d1
cmp.w wd_Height(a1),d1
blo .end_CTF
.in_border move.l a1,d0
.no_border move.l CTF(a5),d1
cmp.l #1,d1
bhi.s .more_thn_1
bsr DoWindowToFront
bra .end_CTF
.more_thn_1 cmp.l ClickWindow(a5),d0
beq.s .same_win
move.l d0,ClickWindow(a5)
moveq #1,d0
move.l d0,ClickCount(a5)
bra.s .save_time
.same_win ; Check to see whether MaxClickDelay has been exceeded. If not
; increment ClickCount and compare with (CTFOption). If equal, do
; a WindowToFront. Window under pointer in D0.
push.l d0
pushm.l d2-d3/a0
move.l ClickTime+TV_SECS(a5),d0
move.l ClickTime+TV_MICRO(a5),d1
move.l ie_TimeStamp+TV_SECS(a0),d2
move.l ie_TimeStamp+TV_MICRO(a0),d3
just DoubleClick
popm.l d2-d3/a0
tst.l d0
beq.s .time_exceeded
addq.l #1,ClickCount(a5)
move.l CTF(a5),d0
cmp.l ClickCount(a5),d0
bhi.s .need_more_clicks
clr.l ClickCount(a5)
pop.l d0
bsr DoWindowToFront
bra.s .end_CTF
.time_exceeded
moveq #1,d0
move.l d0,ClickCount(a5)
.need_more_clicks
pop.l d0
.save_time move.l ie_TimeStamp+TV_SECS(a0),ClickTime+TV_SECS(a5)
move.l ie_TimeStamp+TV_MICRO(a0),ClickTime+TV_MICRO(a5)
.end_CTF pop.l d2
.no_CTF
;*╗╗ Perform acceleration.
tst.l Acceleration(a5)
bmi .end_event
move.l Threshold(a5),d0
bpl.s .T1
moveq #0,d0
.T1 move.w ie_X(a0),d1
bpl.s .PosX
neg.w d1
.PosX cmp.w d0,d1
bls.s .SkipX ;below threshold
move.l Acceleration(a5),d1
muls.w ie_X(a0),d1
bpl.s .SubDampX
add.w DampingConstant(a5),d1
bra.s .DampX
.SubDampX sub.w DampingConstant(a5),d1
.DampX move.w d1,ie_X(a0)
.SkipX move.w ie_Y(a0),d1
bpl.s .PosY
neg.w d1
.PosY cmp.w d0,d1
bls.s .EndAccel
move.l Acceleration(a5),d1
muls.w ie_Y(a0),d1
bpl.s .SubDampY
add.w DampingConstant(a5),d1
bra.s .DampY
.SubDampY sub.w DampingConstant(a5),d1
.DampY move.w d1,ie_Y(a0)
.EndAccel
.end_event popm.l a2/a6
rts
;***************************************************************************
Time_Outs: ;*╗╗ Check for time-outs (mouse and screen blanking)
; Takes d1=TimeStamp seconds; a5=GlobalPtr
; scratches d0, d1, a0, a1
push.l a6
move.l IntBase(a5),a6
;*╗╗ Check if window has changed with blanked pointer
btst #STB_MBlanked,Status(a5)
beq.s .EndMBW ; (Skip if not blanked)
move.l MBlankWindow(a5),d0
cmp.l ib_ActiveWindow(a6),d0
beq.s .EndMBW
bset #STB_DoMBlank,Status(a5)
bsr SignalMouseBlank ; Blank mouse for this new window
.EndMBW:
;*╗╗ Check if mouse should be timed out
tst.l MouseBlank(a5)
ble.s .end_MBlank ; If user-mouse-blank-time=0, don't blank
move.l d1,d0
sub.l MouseBlank(a5),d0 ; this_time - user_pause
tst.l MouseTime(a5)
bne.s .else_MBlnk ; If last-used mouse time is zero, then
move.l d1,MouseTime(a5) ; reset last-used mouse time
bra.s .end_MBlank ; else
.else_MBlnk sub.l MouseTime(a5),d0 ; sub last mouse move time
blo.s .end_MBlank ; If this_time - last_move > user_pause
move.l d0,MouseTime(a5)
bset #STB_DoMBlank,Status(a5)
bsr SignalMouseBlank
.end_MBlank ;endif
tst.l ScreenBlank(a5)
ble.s .end_SBlank ; If screen-blank time-out=0, don't blank
move.l d1,d0
sub.l ScreenBlank(a5),d0 ; this_time - user_pause
tst.l ScreenTime(a5)
bne.s .else_SBlnk ; If last-used screen time is zero then
move.l d1,ScreenTime(a5) ; reset last-used screen time
bra.s .end_SBlank ;else
.else_SBlnk sub.l ScreenTime(a5),d0
blo.s .end_SBlank
bset #STB_SBlanked,Status(a5)
bne.s .end_SBlank ; Don't blank if already blanked
BlankScreen
.end_SBlank ;endif
pop.l a6
rts
;****************************************************************************
SignalMouseBlank: ; Takes a5=GlobalPtr; Returns, Trashes nil
push.l d0
move.l MouseBlankSig(a5),d0
bsr.s SignalTask
pop.l d0
rts
SignalTask: ; Takes a5=GlobalPtr; d0=signal; Trashes nil
pushm.l d0-d1/a0-a1/a6
move.l Task(a5),a1
move.l Execbase,a6
just Signal
popm.l d0-d1/a0-a1/a6
rts
;****************************************************************************